package org.wevil.service.witcher3;

import org.wevil.entity.witcher3.Witcher3Alchemy;
import org.wevil.entity.witcher3.Witcher3AlchemySubstances;
import org.wevil.params.add.witcher3.Witcher3AlchemyAP;
import org.wevil.params.delete.DeleteParam;
import org.wevil.params.detail.DetailParam;
import org.wevil.params.page.witcher3.Witcher3AlchemyPP;
import org.wevil.params.update.witcher3.Witcher3AlchemyUP;
import org.wevil.repo.witcher3.Witcher3AlchemyRepo;
import org.wevil.repo.witcher3.Witcher3AlchemySubstancesRepo;
import org.wevil.util.BeanUtil;
import org.wevil.util.page.PageResult;
import org.wevil.util.page.PageResultUtil;
import org.wevil.vo.detail.witcher3.Witcher3AlchemyDVo;
import org.wevil.vo.list.witcher3.Witcher3AlchemyLVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;

@Service
@Transactional
public class Witcher3AlchemyService {

    @Resource
    Witcher3AlchemyRepo repo;
    @Resource
    Witcher3AlchemySubstancesRepo witcher3AlchemySubstancesRepo;

    /** 创建 */
    public void create(Witcher3AlchemyAP param) {
        Witcher3Alchemy entity = new Witcher3Alchemy();
        BeanUtil.copyPropIgnoreNull(param, entity);
        repo.save(entity);
    }

    /** 修改 */
    public void update(Witcher3AlchemyUP param){
        Witcher3Alchemy entity = new Witcher3Alchemy();
        BeanUtil.copyPropIgnoreNull(param, entity);
        repo.update(entity);
    }

    /** 删除 */
    public void delete(DeleteParam param){
        repo.deleteById(param.getId());
    }

    /** 详情 */
    public Witcher3AlchemyDVo detail(DetailParam param){
        Optional<Witcher3Alchemy> opt = repo.findById(param.getId());
        if(opt.isPresent()){
            Witcher3AlchemyDVo vo = new Witcher3AlchemyDVo();
            BeanUtil.copyPropIgnoreNull(opt.get(), vo);
            return vo;
        }
        return null;
    }

    /** 分页 */
    public PageResult<Witcher3AlchemyLVo> page(Witcher3AlchemyPP param) {
        // 分页参数
        Integer current = param.getCurrent();
        Integer size = param.getSize();
        // 要查询的字段
        String nameEn = param.getNameEn();
        String nameCn = param.getNameCn();
        String type = param.getType();
        Specification<Witcher3Alchemy> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (StringUtils.isNotBlank(nameEn)) {
                predicates.add(cb.like(root.get("nameEn").as(String.class), "%" + nameEn + "%"));
            }
            if (StringUtils.isNotBlank(nameCn)) {
                predicates.add(cb.like(root.get("nameCn").as(String.class), "%" + nameCn + "%"));
            }
            if (StringUtils.isNotBlank(type)) {
                predicates.add(cb.equal(root.get("type").as(String.class), type));
            }
            return cb.and(predicates.toArray(new Predicate[0]));
        };
        Sort sort = Sort.by(Sort.Direction.ASC, "nameEn");
        Pageable pageable = PageRequest.of(current - 1, size, sort);
        Page<Witcher3Alchemy> page = repo.findAll(specification, pageable);
        // 封装返回数据
        Iterator<Witcher3Alchemy> iterator = page.iterator();
        List<Witcher3AlchemyLVo> voList = new ArrayList<>();
        while (iterator.hasNext()) {
            Witcher3Alchemy next = iterator.next();
            Witcher3AlchemyLVo vo = new Witcher3AlchemyLVo();
            BeanUtil.copyPropIgnoreNull(next, vo);
            // 获取材料的子材料名称
            List<String> subs = getSubNames(next.getId());
            vo.setSubs(subs);
            voList.add(vo);
        }
        // 返回
        long total = repo.count(specification);
        return PageResultUtil.generateResult(voList, current, size, total);
    }

    /** 获取子材料的名称 */
    private List<String> getSubNames(Integer id) {
        List<String> names = new ArrayList<>();
        List<Witcher3AlchemySubstances> entitys = witcher3AlchemySubstancesRepo.findByIdAlchemy(id);
        if(!entitys.isEmpty()){
            for(Witcher3AlchemySubstances entity : entitys){
                Integer idSubstance = entity.getIdSubstance();
                Optional<Witcher3Alchemy> opt = repo.findById(idSubstance);
                if(opt.isPresent()){
                    Witcher3Alchemy witcher3Alchemy = opt.get();
                    names.add(witcher3Alchemy.getNameCn());
                }
            }
        }
        return names;
    }
}
